import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart' hide WidgetPaddingX;
import 'package:hotpot/extensions/data.dart';
import 'package:hotpot/models/loyalty_card.dart';
import 'package:hotpot/models/res_partner.dart';
import 'package:hotpot/odoo/odoo_api.dart';
import 'package:hotpot/widgets/styles/icon_box.dart';
import 'package:hotpot/widgets/widget_ext.dart';
import 'package:hotpot/widgets/z_container.dart';
import 'package:hotpot/widgets/z_image.dart';
import 'package:mobile_scanner/mobile_scanner.dart';

class ScanWidget extends StatefulWidget {
  final void Function() onClose;
  final void Function(ResPartner partner)? onSuccess;
  final void Function(String code)? onResult;
  final bool right;

  const ScanWidget(this.onClose, this.onSuccess, {super.key, this.right = true, this.onResult});

  @override
  State<ScanWidget> createState() => _ScanWidgetState();
}

class _ScanWidgetState extends State<ScanWidget> {
  var scanController = MobileScannerController();

  var processing = false;

  double scanWidth = 196.r;

  var page = 0.obs;

  ResPartner? partner;
  var card = LoyaltyCard().obs;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    if (kDebugMode) {
      Timer(1000.milliseconds, () {
        checkCode('042-3474-bdFD');
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    double scanArea = size.height > scanWidth ? scanWidth * 2 / 3 : size.height * 2 / 3;
    return Row(
      children: [
        if (widget.right) const SizedBox(height: double.infinity).gestureDetector(onTap: widget.onClose).expanded(),
        scanBox(size, scanArea),
        emptyBox(),
        userBox(),
        if (!widget.right) const SizedBox(height: double.infinity).gestureDetector(onTap: widget.onClose).expanded(),
      ],
    );
  }

  Color get iconBgColor => Colors.black45;

  double get iconPadding => 2.r;

  radiusList(Size size, double scanArea) {
    double rectSize = 12.r;
    double pointSize = 4.r;
    return [
      Positioned(
        left: 0,
        top: 0,
        bottom: 0,
        child: Container(
          width: (scanWidth - scanArea) / 2 + iconPadding,
          color: iconBgColor,
        ),
      ),
      Positioned(
        right: 0,
        top: 0,
        bottom: 0,
        child: Container(
          width: (scanWidth - scanArea) / 2 + iconPadding,
          color: iconBgColor,
        ),
      ),
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding,
        left: (scanWidth - scanArea) / 2 + iconPadding,
        top: 0,
        child: Container(
          height: (size.height - scanArea) / 2 + iconPadding,
          color: iconBgColor,
        ),
      ),
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding,
        left: (scanWidth - scanArea) / 2 + iconPadding,
        bottom: 0,
        child: Container(
          height: (size.height - scanArea) / 2 + iconPadding,
          color: iconBgColor,
        ),
      ),

      /// tl
      Positioned(
        left: (scanWidth - scanArea) / 2 + iconPadding,
        top: (size.height - scanArea) / 2 + iconPadding,
        child: ClipRRect(
          borderRadius: BorderRadius.only(bottomRight: Radius.circular(10000.r)),
          child: Container(
            height: rectSize,
            width: rectSize,
            color: iconBgColor,
          ),
        ),
      ),
      Positioned(
        left: (scanWidth - scanArea) / 2 + iconPadding + rectSize,
        top: (size.height - scanArea) / 2 + iconPadding,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),
      Positioned(
        left: (scanWidth - scanArea) / 2 + iconPadding,
        top: (size.height - scanArea) / 2 + iconPadding + rectSize,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),

      /// tr
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding,
        top: (size.height - scanArea) / 2 + iconPadding,
        child: ClipRRect(
          borderRadius: BorderRadius.only(bottomLeft: Radius.circular(10000.r)),
          child: Container(
            height: rectSize,
            width: rectSize,
            color: iconBgColor,
          ),
        ),
      ),
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding + rectSize,
        top: (size.height - scanArea) / 2 + iconPadding,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding,
        top: (size.height - scanArea) / 2 + iconPadding + rectSize,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),

      /// br
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding,
        bottom: (size.height - scanArea) / 2 + iconPadding,
        child: ClipRRect(
          borderRadius: BorderRadius.only(topLeft: Radius.circular(10000.r)),
          child: Container(
            height: rectSize,
            width: rectSize,
            color: iconBgColor,
          ),
        ),
      ),
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding + rectSize,
        bottom: (size.height - scanArea) / 2 + iconPadding,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),
      Positioned(
        right: (scanWidth - scanArea) / 2 + iconPadding,
        bottom: (size.height - scanArea) / 2 + iconPadding + rectSize,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),

      /// bl
      Positioned(
        left: (scanWidth - scanArea) / 2 + iconPadding,
        bottom: (size.height - scanArea) / 2 + iconPadding,
        child: ClipRRect(
          borderRadius: BorderRadius.only(topRight: Radius.circular(10000.r)),
          child: Container(
            height: rectSize,
            width: rectSize,
            color: iconBgColor,
          ),
        ),
      ),
      Positioned(
        left: (scanWidth - scanArea) / 2 + iconPadding + rectSize,
        bottom: (size.height - scanArea) / 2 + iconPadding,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),
      Positioned(
        left: (scanWidth - scanArea) / 2 + iconPadding,
        bottom: (size.height - scanArea) / 2 + iconPadding + rectSize,
        child: Container(
          height: pointSize,
          width: pointSize,
          color: iconBgColor,
        ),
      ),
    ];
  }

  void checkCode(String code) async {
    if (widget.onResult == null) {
      partner = await OdooApi.getResPartner(barcode: code);
      if (partner?.barcode == null) {
        page.value = 1;
      } else {
        page.value = 2;
        widget.onSuccess?.call(partner!);
        card.value = await OdooApi.getLoyaltyCard(userId: partner!.id, programType: 'loyalty');
      }
    } else {
      widget.onResult!(code);
    }
  }

  scanBox(Size size, double scanArea) {
    return Obx(
      () => ZContainer(
        width: 196,
        // color: const Color(0xFF1F1D2B),
        child: Stack(
          alignment: Alignment.center,
          children: [
            SizedBox(
              width: scanWidth,
              height: size.height,
              child: MobileScanner(
                fit: BoxFit.cover,
                controller: scanController,
                // scanWindow: Rect.fromLTWH(
                //   (scanWidth - scanArea) / 2,
                //   (size.height - scanArea) / 2,
                //   (scanWidth + scanArea) / 2,
                //   (size.height + scanArea) / 2,
                // ),
                onDetect: (BarcodeCapture barcodes) {
                  if (processing) return;
                  processing = true;
                  var code = barcodes.barcodes.first.rawValue;
                  if (code is String) {
                    checkCode(code);
                  }
                },
              ),
            ),
            // ...radiusList(size, scanArea),
            // Positioned(
            //   left: (scanWidth - scanArea) / 2,
            //   top: (size.height - scanArea) / 2,
            //   child: SizedBox(
            //     width: scanArea,
            //     height: scanArea,
            //     child: 'images/scan_image.png'.assetImage(),
            //   ),
            // ),
          ],
        ),
      ).visibility(page.value == 0),
    );
  }

  emptyBox() {
    return Obx(
      () => ZContainer(
        width: 196,
        color: const Color(0xFF1F1D2B),
        child: Column(
          children: [
            const IconBox(Icons.highlight_remove_rounded, 18, 16, bgColor: Colors.transparent)
                .paddingOnly(top: 9, right: 9)
                .gestureDetector(onTap: widget.onClose)
                .alignRight(),
            157.hSizedBox,
            'images/img_user_empty.png'.assetImage(width: 108),
            17.hSizedBox,
            'No se encontró ningún cliente'.text(size: 8, color: Colors.white, bold: true),
          ],
        ),
      ).visibility(page.value == 1),
    );
  }

  userBox() {
    return Obx(
      () => ZContainer(
        width: 196,
        color: const Color(0xFF1F1D2B),
        child: Column(
          children: [
            const IconBox(Icons.highlight_remove_rounded, 18, 16, bgColor: Colors.transparent)
                .paddingOnly(top: 9, right: 9)
                .gestureDetector(onTap: widget.onClose)
                .alignRight(),
            22.hSizedBox,
            Stack(
              children: [
                const ZContainer(
                  width: 52,
                  height: 50,
                  radius: 8,
                  margin: EdgeInsets.only(top: 2),
                  color: Color(0xFF252836),
                ).alignCenter(),
                ZImage.memory(bytes: partner?.image128.bytes, width: 37, height: 37).paddingOnly(top: 10).alignCenter(),
                const IconBox(Icons.close, 9, 7, bgColor: Colors.red).positioned(right: 69),
              ],
            ).sizedBox(width: 196),
            15.hSizedBox,
            'Hola!\n${partner?.name}'.text(textAlign: TextAlign.center, size: 8, color: Colors.white, bold: true, maxLines: 2),
            33.hSizedBox,
            Stack(
              children: [
                'images/img_user_card.png'.assetImage(width: 180, fit: BoxFit.fitWidth),
                'Tarjeta de Punto'.text(size: 8, bold: true, color: Colors.white).paddingOnly(top: 11, left: 18),
                (partner?.barcode ?? '')
                    .text(size: 8, bold: true, color: Colors.white, textAlign: TextAlign.center)
                    .sizedBox(width: 180)
                    .paddingOnly(top: 54),
                card.value.points.fixed
                    .text(size: 8, bold: true, color: Colors.white, textAlign: TextAlign.end)
                    .sizedBox(width: 169)
                    .paddingOnly(top: 101),
              ],
            ),
          ],
        ),
      ).visibility(page.value == 2),
    );
  }
}
